/*
 * Copyright 2011-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sabayframework.mem;

import java.io.Closeable;
import java.nio.ByteBuffer;

import org.sabayframework.channel.Channel;
import org.sabayframework.mem.Transaction.Locking;
import org.sabayframework.queue.ExecutionQueue;
/*

Problems:
  
- record co-location: how to store related records on the same computer, in the same 
  time evenly distribute unrelated records
  solution: use computerId.hashCode as upper part of record address and use it as
  a key in Cluster consistent hashing for selecting computer and replicas
  drawbacks: fixed distribution strategy for records, heavy usage of one of the partitions could cause OutOfMemory
     
- support hundreds of thousands of long-running transactions
  solution:  
  start new transaction for query 
  create a query record in a separate transaction where store query text, params 
  and query transaction id.
  if query transaction fails due to hardware then restart transaction and update 
  query record.  
  if query transaction is successful then delete query record.

 * */
/**
 * Interface of memory space. Memory space is a transactional storage 
 * for Memorizable objects.
 * @author Alex Antonau
 * */
public interface Space extends Closeable {
			
	/**
	 * Begin new transaction in this memory space with given locking strategy.
	 * @param locking locking strategy defines how transaction will control 
	 * concurrent modifications.
	 * @return transaction reference
	 * */
	Transaction beginTransaction(Locking locking);

	/**
	 * Find an existing transaction by transaction id.
	 * @param txId transaction id
	 * @return channel for acquiring transaction reference. 
	 * */
	Channel<Transaction> getTransaction(long txId);
	
	/**
	 * Returns ID generator for this space.
	 * */
	IdGenerator getIdGenerator();
	/**
	 * Returns execution queue for this space
	 * */
	ExecutionQueue getExecutionQueue();
	
    /**
     * Wraps a byte array into a big buffer.
     *
     * <p> The new buffer will be backed by the given byte array;
     * that is, modifications to the buffer will cause the array to be modified
     * and vice versa.  The new buffer's capacity will be
     * <tt>length</tt>, its position will be <tt>0</tt>,and its limit
     * will be <tt>length</tt>.  Its
     * {@link BigBuffer#array </code>backing array<code>} will be the given array, and
     * its {@link BigBuffer#arrayOffset </code>array offset<code>} will be <tt>offset</tt>.  </p>
     *
     * @param  array
     *         The array that will back the new buffer
     *
     * @param  offset
     *         The offset of the subarray to be used; must be non-negative and
     *         no larger than <tt>array.length</tt>.  
     *
     * @param  length
     *         The length of the subarray to be used;
     *         must be non-negative and no larger than
     *         <tt>array.length - offset</tt>.
     *         The new buffer's capacity and limit will be set to <tt>length</tt>.
     *
     * @return  The new big buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
     *          parameters do not hold
     */
    BigBuffer wrap(byte[] array,  int offset, int length);
    
	/**
	 * Wraps a byte buffer into a big buffer.
	 * Long parameter values to the resulting buffer should not 
	 * exceed Integer.MAX_INT value.
	 * @param buffer The byte buffer that will back the new buffer
     * @return  The new big buffer
	 * */
    BigBuffer wrap(ByteBuffer buffer);

    /**
     * Allocates a new direct buffer.
     * The new buffer's position will be zero,and its limit will be its capacity. 
     * Whether or not it has a backing array is unspecified.
     * @param capacity - The new buffer's capacity, in bytes
     * @return  The new big buffer
     * */
    BigBuffer allocateDirect(long capacity);
    /**
     * Allocates a new buffer backed by a byte array from heap.
     * The new buffer's position will be zero,and its limit will be its capacity. 
     * @param capacity - The new buffer's capacity, in bytes
     * @return  The new big buffer
     * */
    BigBuffer allocate(int capacity);
}
